//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_META_DATA_FUNC_H
#define _UX_META_DATA_FUNC_H

#include "../Defines/Defines.h"

namespace Engine
{

namespace UXTypes
{
	class IMetaBaseType;

}	// UXTypes



	// helpers macro
#define _CREATE_META_OBJECT_T( _type, _meta_class ) \
	template <> \
	inline IMetaBaseType * CreateMetaObjectTempl(const char *pName, usize uOffset, usize uSize) \
	{ \
		return new CMetaObjectType( pName, uOffset, _meta_class.GetObject()->GetObj() ); \
	}


#define _CREATE_META_OBJECT_FD( _type ) \
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, _type& obj)


#define _CREATE_META_OBJECT( _type, _meta_class ) \
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, _type& obj) \
	{ \
		return new CMetaObjectType( pName, uOffset, _meta_class.GetObject()->GetObj() ); \
	}
	

	// override this function while add new meta object

	template <typename T>
	inline IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, T& obj)
	{
		STATIC_WARNING( "unknown type" );
		return nullptr;
	}

	
	// override this function while add new meta object

	template <typename T>
	inline IMetaBaseType * CreateMetaObjectTempl(const char *pName, usize uOffset, usize uSize)
	{
		T	temp;
		return CreateMetaObject( pName, uOffset, uSize, temp );
	}


	template <usize Size>
	inline IMetaBaseType * __CreateNearTypeMetaObj(const char *pName, usize uOffset, usize uSize)
	{
		STATIC_WARNING( "unknown type" );
		return nullptr;
	}


	
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, bool &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, int8 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, int16 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, int32 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, int64 &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, float &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, double &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, float32_t &obj);
	IMetaBaseType * CreateMetaObject(const char *pName, usize uOffset, usize uSize, float64_t &obj);
	

#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline IMetaBaseType * CreateMetaObjectTempl<_type>(const char *pName, usize uOffset, usize uSize) \
	{ \
		_type	temp; \
		return CreateMetaObject( pName, uOffset, uSize, temp ); \
	}

	_CREATE_DEF_META_OBJECT( bool );
	_CREATE_DEF_META_OBJECT( int8 );
	_CREATE_DEF_META_OBJECT( int16 );
	_CREATE_DEF_META_OBJECT( int32 );
	_CREATE_DEF_META_OBJECT( int64 );
	_CREATE_DEF_META_OBJECT( float );
	_CREATE_DEF_META_OBJECT( double );
	_CREATE_DEF_META_OBJECT( float32_t );
	_CREATE_DEF_META_OBJECT( float64_t );

#undef  _CREATE_DEF_META_OBJECT
	
	
	
#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline IMetaBaseType * __CreateNearTypeMetaObj<sizeof(_type)>(const char *pName, usize uOffset, usize uSize) \
	{ \
		return CreateMetaObjectTempl<_type>( pName, uOffset, uSize ); \
	}
	
	_CREATE_DEF_META_OBJECT( int8  );
	_CREATE_DEF_META_OBJECT( int16 );
	_CREATE_DEF_META_OBJECT( int32 );
	_CREATE_DEF_META_OBJECT( int64 );

#undef  _CREATE_DEF_META_OBJECT

	
#define _CREATE_DEF_META_OBJECT( _type ) \
	template <> \
	inline IMetaBaseType * CreateMetaObjectTempl<_type>(const char *pName, usize uOffset, usize uSize) \
	{ \
		return __CreateNearTypeMetaObj<sizeof(_type)>( pName, uOffset, uSize ); \
	}
	
	_CREATE_DEF_META_OBJECT( uint8  );
	_CREATE_DEF_META_OBJECT( uint16 );
	_CREATE_DEF_META_OBJECT( uint32 );
	_CREATE_DEF_META_OBJECT( uint64 );
	
#undef  _CREATE_DEF_META_OBJECT

//-------------------------------------------------------------------

}	// Engine

#endif	// _UX_META_DATA_FUNC_H